<?php
//
//  Zsearcher
//
//  Created by Elliot Yap on 2011-09-15.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

class Zsearcher {
	
	# passed in model
	private $_model;
	# row info
	private $_pageParam;
	# result
	private $_result;
	
	public $url;
	
	function Zsearcher ( $model ){
		
		$this->_model = $model;
		
		# ROW INFO
		# get page param
		$this->_pageParam = $model->pageParam;
		
		# get page number, cool
		$this->_pageParam['currentPageNumber'] 	= intval(isset($_GET['page'])&&$_GET['page']>=1)?intval($_GET['page']):1;
		$this->_pageParam['currentPage']		= $this->_pageParam['currentPageNumber']-1;
		
		# CONDITION
		# filter condition from GET
		$filteredCondition = array();
		$filter = array_keys($model->conditionParam);
		foreach ($filter as $key)
			if ( isset($_GET[$key]) && !empty($_GET[$key]) )
				$filteredCondition[$key] = $_GET[$key];
		
		# PAGER
		$pagerFilteredCondition = $filteredCondition;
		foreach ( array('sortcol','sortdir') as $key) {
			if ( isset($_GET[$key]) && !empty($_GET[$key]) )
				$pagerFilteredCondition[$key] = $_GET[$key];
		}
		$this->url = $this->_pagerBuildBasePath($pagerFilteredCondition);
		
		# construct condition string, param from model
		$this->condition = $model->genQueryCondition($filteredCondition);
		
		# construct condition order
		$_GET['sortdir'] = (isset($_GET['sortdir']))?$_GET['sortdir']:$model->table['defaultSortDir'];
		$_GET['sortcol'] = (isset($_GET['sortcol']))?$_GET['sortcol']:$model->table['defaultSortCol'];
		$this->condition['order'] = $_GET['sortcol'].' '.$_GET['sortdir'];
		
		
	}
	
	public function normalSearch() {
		$this->_search();
	}
	public function getPager() {

		$this->_pageParam['pagerLimit'] = 10;
		# page range
		$this->_pageParam['pageStart']  
				= ($this->_pageParam['currentPageNumber']-$this->_pageParam['pagerLimit']/2 <=0 ) ? 
					1 : intval(($this->_pageParam['currentPageNumber']-$this->_pageParam['pagerLimit']/2 ));
		$this->_pageParam['pageEnded']
				= (ceil($this->_pageParam['currentPageNumber']+$this->_pageParam['pagerLimit']/2) >= ceil($this->_pageParam['itemCount']/$this->_pageParam['pageSize'])) ?
					ceil($this->_pageParam['itemCount']/$this->_pageParam['pageSize']) :
					ceil($this->_pageParam['currentPageNumber']+$this->_pageParam['pagerLimit']/2);
		$this->_pageParam['pageRange'] = ($this->_pageParam['pageEnded']<=1) ?
			false : 
			range ( $this->_pageParam['pageStart'] , $this->_pageParam['pageEnded'] );
		
		$pager = $this->_pageParam;
		ob_start();
		require 'view-pager.php';
		return ob_get_clean();

		# for c link pager
		$this->_pageParam['CLinkPager'] = array();
		$keys = array('pageSize','nextPageLabel','prevPageLabel','firstPageLabel','lastPageLabel','header','cssFile','itemCount','currentPage');
		foreach ( $this->_pageParam as $key => $row) {
			if ( in_array($key,$keys)) {
				$this->_pageParam['CLinkPager'][$key] = $row;
			}
		}
		//echo "<pre>"; print_r( $this->_pageParam ); exit;
		return $this->_pageParam;
	}
	public function getFilter() {
		ob_start();
		require 'view-filter.php';
		return ob_get_clean();
	}
	public function getResult() {
		return $this->_result;
	}

	private function _search() {
		
		#init
		$t = $this->_model->table;
		
		# count total row from result
		$this->_pageParam['itemCount'] = $this->_pageCount($this->condition);
		
		# setup row info with total row count result
		$this->_initRowInfo($this->_pageParam);

		# sql query with limit row begin , page size
		$command = Yii::app()->db->createCommand()
			->select($t['fieldNames'])
			->from($t['tableName']);
		
		if ($t['leftTableName']) {
			$command->leftJoin($t['leftTableName'],$t['leftJoinOn']);
		}

		$this->_result = $command->where($this->condition['string'],$this->condition['params'])
			->order($this->condition['order'])
			->limit($this->_pageParam['pageSize'],$this->_pageParam['rowBegin']-1)
			->queryAll();
			
		# start of inner query
		
		if ( $t['hasManyTableName'] ) {
			
			$ids = array();
			foreach ($this->_result as $row) {
				array_push($ids,$row[$t['hasManyKey']]);
			}
			$subResult = Yii::app()->db->createCommand()
				->select($t['hasManyFieldNames'])
				->from($t['hasManyTableName'])
				->where(array('in','id',$ids))
				->queryAll();

			#merge inner query
			$tmp = array();
			foreach ($subResult as $row) {
				if (!isset( $tmp[$row['id']] )) {
					$tmp[$row['id']] = array();
				}
				$tmp[$row['id']] = $row;
			}
			foreach ($this->_result as $key => $row) {
				if (isset($tmp[$row[$t['hasManyKey']]])) {
					$this->_result[$key]['inner'] = $tmp[$row[$t['hasManyKey']]];
				}
			}
		}
		
		if ( isset($t['belongToTableName']) && $t['belongToTableName']!==false ) {
			
			$ids = array();
			foreach ($this->_result as $row) {
				array_push($ids,$row['id']);
			}
			$subResult = Yii::app()->db->createCommand()
				->select($t['belongToFieldNames'])
				->from($t['belongToTableName'])
				->where(array('in',$t['belongToKey'],$ids))
				->queryAll();
			
			foreach ($this->_result as $key => $row) {
				foreach ($subResult as $subrow) {
					if ($subrow[$t['belongToKey']]==$row['id']) {
						if (!isset( $this->_result[$key]['belongTo'] )) {
							$this->_result[$key]['belongTo'] = array();
						}
						$this->_result[$key]['belongTo'][$subrow['id']] = $subrow;
					}
				}
			}
		}
		
		if ( isset($t['belongToTableName2']) && $t['belongToTableName2']!==false ) {
			
			$ids = array();
			foreach ($this->_result as $row) {
				array_push($ids,$row['id']);
			}
			$subResult = Yii::app()->db->createCommand()
				->select($t['belongToFieldNames2'])
				->from($t['belongToTableName2'])
				->where(array('in',$t['belongToKey2'],$ids))
				->queryAll();
			
			foreach ($this->_result as $key => $row) {
				foreach ($subResult as $subrow) {
					if ($subrow[$t['belongToKey2']]==$row['id']) {
						if (!isset( $this->_result[$key]['belongTo2'] )) {
							$this->_result[$key]['belongTo2'] = array();
						}
						$this->_result[$key]['belongTo2'][$subrow['id']] = $subrow;
					}
				}
			}
		}

	}
	
	
	private function _pageCount($condition) {
		
		$t = $this->_model->table;
		
		# sql count result
		$command = Yii::app()->db->createCommand()
			->select('count('.$t['countFieldName'].') as count')
			->from($t['tableName']);
		
		if ($t['leftTableName']) {
			$command->leftJoin($t['leftTableName'],$t['leftJoinOn']);
		}
		$rsCount = $command->where($this->condition['string'],$this->condition['params'])
			->queryRow();
			
		return $rsCount['count'];
	}
	
	# call after total row count result
	private function _initRowInfo($pageParam) {
		$this->_pageParam['rowBegin'] = 
			( $pageParam['itemCount'] === '0' ) ? 
				0 : 
				( $pageParam['currentPageNumber'] - 1 ) * $pageParam['pageSize'] + 1;
		$this->_pageParam['rowEnded'] = 
			( $pageParam['currentPageNumber'] * $pageParam['pageSize'] <= $pageParam['itemCount'] ) ? 
				$pageParam['currentPageNumber'] * $pageParam['pageSize'] : 
				$pageParam['itemCount'];
		# row range
		$this->_pageParam['rowRange'] = ($this->_pageParam['rowBegin']===0) ?
			false : 
			range ( $this->_pageParam['rowBegin'] , $this->_pageParam['rowEnded'] );

	}
	
	private function _pagerBuildBasePath($pagerFilteredCondition) {
		$searchParamArrayString = array();
		$param = '';
		if (!empty($pagerFilteredCondition)) {
			foreach ($pagerFilteredCondition as $key => $row) {
				array_push( $searchParamArrayString , $key.'='.$row );
			}
			$param = implode('&',$searchParamArrayString);
		}
		return	Yii::app()->controller->uniqueId.'/'.
				Yii::app()->controller->action->id.'/?'.$param;
	}

}